﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DataModels.Common;
using DataModels.Enumerations;
using GenericTools;
using GenericTools.ReportProcessing;
using ReportingManagement.Models;

namespace ReportingManagement.Components
{
    public partial class SMSUserDetails : Form
    {
        private const string SI = "Strategic Information Associate";
        private const string FACILITY_OTHERS = "00000000";
        private const string FACILITY_REGION = "000000";
        private const string FACILITY_DISTRICT = "0000";
        private enum SMSReportingLevel { FACILITY, DISTRICT, REGION, OTHERS };
        SMSReportingLevel m_ReportingLevel = SMSReportingLevel.OTHERS;

        private UserTitle m_Title = UserTitle.DATA_CLERK;

        private int m_UserId = -1;
        private string m_PhoneNumber = String.Empty;
        private string m_Fullname = String.Empty;
        private int m_LanguageID = -1;
        private string m_FacilityCode = String.Empty;
        private string m_EmailAddress = String.Empty;

        private UserInformation m_ActionUser;
        private bool m_UserLoaded = false;
        private bool m_UpdatingUser = false;

        private SMSUserViewModel _smsUserViewModel = null;
        private bool _Deleted = false;

        /// <summary>
        /// Creates a new instance of SMS User details
        /// </summary>
        /// <param name="actionUserId">Unique identifier of Application who may modify some information regarding this instance</param>
        public SMSUserDetails(UserInformation actionUser)
        {
            InitializeComponent();
            this.m_ActionUser = actionUser;
            m_UpdatingUser = false;
            btnDelete.Enabled = false;
            _Deleted = false;

            cboPreferredLanguage.Items.Clear();
            DataTable dataTable = Utilities.GetAllLanguages();
            foreach (DataRow r in dataTable.Rows)
            {
                ListItem item = new ListItem();
                item.Text = r["Language"].ToString();
                item.Value = r["LangID"];
                cboPreferredLanguage.Items.Add(item);
            }
            if (cboPreferredLanguage.Items.Count > 0) cboPreferredLanguage.SelectedIndex = 0;
        }

        /// <summary>
        /// Creates an instance of SMS User details
        /// </summary>
        /// <param name="userId">Unique identifier of SMS User</param>
        /// <param name="actionUserId">Unique identifier of Application who may modify some information regarding this instance</param>
        public SMSUserDetails(int userId, /*SMSUserViewModel userViewModel,*/  UserInformation actionUser)
        {
            InitializeComponent();
            //this._smsUserViewModel = userViewModel;

            m_UserId = userId;
            m_ActionUser = actionUser;
            m_UpdatingUser = true;
            txtPhoneNumber.ReadOnly = true;

            cboPreferredLanguage.Items.Clear();
            DataTable dataTable = Utilities.GetAllLanguages();
            foreach (DataRow r in dataTable.Rows)
            {
                ListItem item = new ListItem();
                item.Text = r["Language"].ToString();
                item.Value = r["LangID"];
                cboPreferredLanguage.Items.Add(item);
            }
            if (cboPreferredLanguage.Items.Count > 0) cboPreferredLanguage.SelectedIndex = 0;
            LoadUserDetails();
        }

        private void rdoFacility_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoFacility.Checked)
            {                
                DataTable dataTable = Utilities.GetAllFacilitiesStatus();
                if (this.m_ActionUser.Level == AccessLevel.ADMINISTRATOR) dataTable = Utilities.GetAllFacilitiesStatus();
                else dataTable = Utilities.GetAllFacilitiesStatus(this.m_ActionUser.SupportingPartnerId);

                cboReportingLevel.Items.Clear();
                foreach (DataRow r in dataTable.Rows)
                {
                    ListItem item = new ListItem();
                    item.Text = r["Facility Name"].ToString();
                    item.Value = r["Facility Code"];
                    cboReportingLevel.Items.Add(item);
                }
                if (cboReportingLevel.Items.Count > 0) cboReportingLevel.SelectedIndex = 0;
            }
        }

        private void rdoDistrict_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoDistrict.Checked)
            {                
                DataTable dataTable = null;
                if (this.m_ActionUser.Level == AccessLevel.ADMINISTRATOR) dataTable = Utilities.GetAllDistricts();
                else dataTable = Utilities.GetAllDistricts(this.m_ActionUser.SupportingPartnerId);

                cboReportingLevel.Items.Clear();
                foreach (DataRow r in dataTable.Rows)
                {
                    ListItem item = new ListItem();
                    item.Text = r["District"].ToString();
                    item.Value = String.Format("{0}0000", r["DistrictCode"]);
                    cboReportingLevel.Items.Add(item);
                }
                if (cboReportingLevel.Items.Count > 0) cboReportingLevel.SelectedIndex = 0;
            }
        }

        private void rdoRegion_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoRegion.Checked)
            {                
                DataTable dataTable = null;                
                if (this.m_ActionUser.Level == AccessLevel.ADMINISTRATOR) dataTable = Utilities.GetAllRegions();
                else dataTable = Utilities.GetAllRegions(this.m_ActionUser.SupportingPartnerId);

                cboReportingLevel.Items.Clear();
                foreach (DataRow r in dataTable.Rows)
                {
                    ListItem item = new ListItem();
                    item.Text = r["RegionName"].ToString();
                    item.Value = String.Format("{0}000000", r["RegionCode"]);
                    cboReportingLevel.Items.Add(item);
                }
                if (cboReportingLevel.Items.Count > 0) cboReportingLevel.SelectedIndex = 0;
            }
        }

        private void rdoOthers_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoOthers.Checked)
            {
                cboReportingLevel.Items.Clear();
                ListItem item = new ListItem();
                item.Text = SI;
                item.Value = "00000000";
                cboReportingLevel.Items.Add(item);
                cboReportingLevel.SelectedIndex = 0;
            }
        }

        private void btnSaveChanges_Click(object sender, EventArgs e)
        {
            bool okToContinue = ValidateInputs();
            if (okToContinue)
            {
                try
                {
                    btnSaveChanges.Enabled = false;
                    Application.DoEvents();
                    bool saved = false;
                    int userId = m_UserId;
                    
                    string phoneNumber = txtPhoneNumber.Text;
                    m_PhoneNumber = phoneNumber;

                    string fullname = txtFullname.Text;
                    m_Fullname = fullname;

                    string email = txtEmailAddress.Text;
                    m_EmailAddress = email;

                    ListItem item = (ListItem)cboPreferredLanguage.SelectedItem;
                    
                    int language = Int32.Parse(item.Value.ToString());
                    m_LanguageID = language;

                    item = (ListItem)cboReportingLevel.SelectedItem;
                    string facilityCode = item.Value.ToString();
                    m_FacilityCode = facilityCode;

                    if (rdoFacility.Checked) m_Title = UserTitle.DATA_CLERK;
                    if (rdoDistrict.Checked) m_Title = UserTitle.DRCHCO;
                    if (rdoRegion.Checked) m_Title = UserTitle.RRCHCO;
                    if (rdoOthers.Checked) m_Title = UserTitle.SI;

                    int titleId = (int)m_Title;

                    if (m_UpdatingUser)
                    {
                        saved = Utilities.UpdateSMSUser(m_UserId, phoneNumber, fullname, language, facilityCode,
                            email, titleId, this.m_ActionUser.ID);
                        if (saved)
                        {
                            MessageBox.Show(this, "Operation completed successfully", AppConfiguration.ApplicationName,
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                            this.DialogResult = System.Windows.Forms.DialogResult.OK;
                            this.Close();
                        }
                        else throw new Exception("User cannot be updated at this time. Try again later");
                    }
                    else
                    {
                        saved = Utilities.AddSMSUser(phoneNumber, fullname, language, facilityCode, email,
                            titleId, this.m_ActionUser.ID);
                        if (saved)
                        {
                            /*_smsUserViewModel = new SMSUserViewModel();
                            _smsUserViewModel.FacilityCode = facilityCode;
                            _smsUserViewModel.FacilityName = "";
                            _smsUserViewModel.Name = fullname;
                            _smsUserViewModel.PhoneNumber = phoneNumber;*/

                            MessageBox.Show(this, "Operation completed successfully", AppConfiguration.ApplicationName,
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                            this.DialogResult = System.Windows.Forms.DialogResult.OK;
                            this.Close();
                        }
                        else throw new Exception("User cannot be added at this time. Try again later");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this,
                        String.Format("Operation did not completed successfully{0}{0}{1}", Environment.NewLine, ex.Message),
                        AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    btnSaveChanges.Enabled = true;
                }
            }
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            if (m_UpdatingUser) LoadUserDetails();
            else
            {
                txtFullname.Clear();
                txtPhoneNumber.Clear();
                txtEmailAddress.Clear();

                rdoOthers.Checked = true;
                if (cboPreferredLanguage.Items.Count > 0) cboPreferredLanguage.SelectedIndex = 0;
                if (cboReportingLevel.Items.Count > 0) cboReportingLevel.SelectedIndex = 0;
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            DialogResult response = MessageBox.Show(this,
                String.Format("Are you sure you want to delete SMS user: {0}", m_Fullname),
                AppConfiguration.ApplicationName, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (response == System.Windows.Forms.DialogResult.Yes)
            {
                try
                {
                    btnDelete.Enabled = false;
                    Application.DoEvents();
                    bool deleted = Utilities.DeleteSMSUser(m_UserId, this.m_ActionUser.ID);
                    if (deleted)
                    {
                        _Deleted = true;
                        MessageBox.Show(this, "Operation completed successfully", AppConfiguration.ApplicationName,
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                        this.DialogResult = System.Windows.Forms.DialogResult.OK;
                        this.Close();
                    }
                    else throw new Exception("User cannot be deleted at this time. Try again later.");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, 
                        String.Format("Operation did not completed successfully{0}{0}{1}", Environment.NewLine, ex.Message),
                        AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    btnDelete.Enabled = true;
                }
            }
        }

        private bool ValidateInputs()
        {
            if (String.IsNullOrEmpty(txtFullname.Text))
            {
                MessageBox.Show(this, "Please provide full name.", 
                    AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtFullname.Focus();
                return false;
            }

            if (String.IsNullOrEmpty(txtPhoneNumber.Text))
            {
                MessageBox.Show(this, "Please provide valid phone number.",
                   AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtPhoneNumber.Focus();
                return false;
            }
            return true;
        }

        private void LoadUserDetails()
        {
            if (!m_UserLoaded)
            {
                DataTable dataTable = Utilities.GetSMSUser(m_UserId);
                DataRow row = dataTable.Rows[0];
                m_FacilityCode = row["FacCode"].ToString();
                m_Fullname = row["Name"].ToString();
                m_LanguageID = Int32.Parse(row["LangID"].ToString());
                m_PhoneNumber = row["CellNum"].ToString();
                m_EmailAddress = row["Email"].ToString();
                bool.TryParse(row["Deleted"].ToString(), out _Deleted);

                m_ReportingLevel = SMSReportingLevel.FACILITY;
                if (m_FacilityCode.EndsWith(FACILITY_DISTRICT)) m_ReportingLevel = SMSReportingLevel.DISTRICT;
                if (m_FacilityCode.EndsWith(FACILITY_REGION)) m_ReportingLevel = SMSReportingLevel.REGION;
                if (m_FacilityCode == FACILITY_OTHERS) m_ReportingLevel = SMSReportingLevel.OTHERS;

                this.Text = String.Format("{0}: {1}", this.Text, m_Fullname);
                m_UserLoaded = true;
            }

            txtFullname.Text = m_Fullname;
            txtEmailAddress.Text = m_EmailAddress;
            txtPhoneNumber.Text = m_PhoneNumber;
            if (m_ReportingLevel == SMSReportingLevel.FACILITY) rdoFacility.Checked = true;
            if (m_ReportingLevel == SMSReportingLevel.DISTRICT) rdoDistrict.Checked = true;
            if (m_ReportingLevel == SMSReportingLevel.REGION) rdoRegion.Checked = true;
            if (m_ReportingLevel == SMSReportingLevel.OTHERS) rdoOthers.Checked = true;

            Application.DoEvents(); // Ensures the checkboxes events are taken care.
            for (int i = 0; i < cboReportingLevel.Items.Count; i++)
            {
                ListItem item = (ListItem)cboReportingLevel.Items[i];
                string value = item.Value.ToString();
                if (value == m_FacilityCode)
                {
                    cboReportingLevel.SelectedIndex = i;
                    break;
                }
            }

            for (int i = 0; i < cboPreferredLanguage.Items.Count; i++)
            {
                ListItem item = (ListItem)cboPreferredLanguage.Items[i];
                string value = item.Value.ToString();
                if (value == m_LanguageID.ToString())
                {
                    cboPreferredLanguage.SelectedIndex = i;
                    break;
                }
            }
        }

        #region Public Properties
        public SMSUserViewModel SMSUserViewModel
        {
            get
            {
                if (_smsUserViewModel == null)
                {
                    _smsUserViewModel = new SMSUserViewModel();
                    _smsUserViewModel.Name = m_Fullname;
                    _smsUserViewModel.PhoneNumber = m_PhoneNumber;
                    _smsUserViewModel.FacilityCode = m_FacilityCode;
                    
                    ListItem item = cboReportingLevel.SelectedItem as ListItem;
                    if (item != null)
                    {
                        switch (m_ReportingLevel)
                        {
                            case SMSReportingLevel.FACILITY:
                                _smsUserViewModel.FacilityName = item.Text;
                                DataTable facilityInfo = Utilities.GetFacilityDetails(item.Value.ToString());
                                if (facilityInfo.Rows.Count > 0)
                                {
                                    DataRow row = facilityInfo.Rows[0];
                                    string districtName = row["DistrictName"].ToString();
                                    string regionName = row["RegionName"].ToString();
                                    _smsUserViewModel.DistrictName = districtName;
                                    _smsUserViewModel.RegionName = regionName;
                                }
                                break;

                            case SMSReportingLevel.DISTRICT:
                                _smsUserViewModel.DistrictName = item.Text;
                                int districtId = int.Parse(item.Value.ToString());
                                DataTable regionInfo = Utilities.GetDistrictRegion(districtId);
                                if (regionInfo.Rows.Count > 0)
                                {
                                    DataRow row = regionInfo.Rows[0];
                                    string regionName = row["RegionName"].ToString();
                                    _smsUserViewModel.RegionName = regionName;
                                }
                                break;

                            case SMSReportingLevel.REGION:
                                _smsUserViewModel.RegionName = item.Text;
                                _smsUserViewModel.DistrictName = string.Empty;
                                break;
                        }
                    }
                }
                return _smsUserViewModel;
            }
        }

        public string PhoneNumber
        {
            get { return m_PhoneNumber; }
        }

        public bool Deleted
        {
            get { return _Deleted;  }
        }
        #endregion
    }
}
